/*
 * PhotonRTOS础光实时操作系统 -- 精确计数实现
 *
 * Copyright (C) 2022, 2023 国科础石(重庆)软件有限公司
 *
 * 作者: Baoyou Xie <xiebaoyou@kernelsoft.com>
 *
 * License terms: GNU General Public License (GPL) version 3
 *
 */

#include <photon/accurate_counter.h>
#include <photon/bug_build.h>
#include <std/IfxCpu_IntrinsicsGnuc.h>
#include <asm/barrier.h>


long arch_accurate_add(long i, struct accurate_counter *v)
{
	long result;
	long value, swap_value;

	value = v->counter;
	do {
		swap_value = (long)__cmpAndSwap(((long *)&v->counter), v->counter + i, value);
		value = v->counter;
	} while (swap_value == value);

	return swap_value;
}

long arch_accurate_sub(long i, struct accurate_counter *v)
{
	long result;
	long value, swap_value;

	value = v->counter;
	do {
		swap_value = (long)__cmpAndSwap(((long *)&v->counter), v->counter - i, value);
		value = v->counter;
	} while (swap_value == value);

	return swap_value;
}

long arch_accurate_cmpxchg(struct accurate_counter *ptr, long old, long new)
{
	long oldval;
	unsigned long res;

	smp_mb();
	oldval = (long)__cmpAndSwap(((intptr_t *)&ptr->counter), new, old);
	smp_mb();
	return oldval;
}
